//  该js文件 , 用于 , 客户端通过密钥 , ;连接TIM , 并且 , 接收来自服务端的消息 , 并向Tim 发送消息
//引入相关的依赖包,
import tim from '@/tim'
import TIM from 'tim-js-sdk'
import {Message} from 'element-ui'
import Vue from 'vue'

// 关于 , 用户登录到tim , 的全局方法函数
const getDefaultState = () => {
  //vuex 里面的数据
  return {
    isLogin: false,         // tim是否登录

    isSDKReady: false,      // TIM SDK 是否 准备好

    currentUserProfile: {}, // 用户信息

    currentMemberList: [],  // 会话列表 ///不知道要干什么 ////////////////////

    currentConversation: {},// 用户的 当前会话

    currentMessageList: [], // 当前会话的 聊天记录

    nextReqMessageID: '',   // 当前会话的 下一条消息的id

    isCompleted: false,     // 当前会话列表 , 是否已经拉完了所有的消息

    conversationList: [],   // 所有的 会话列表

    intervalID: 0,          // 当前时间

    message: undefined
  }
}
const state = getDefaultState()

//操作Vuex 里面数据的函数 , 用于 . 直接操作数据
const mutations = {
  // 显示提示消息，比如失败的消息等等
  showMessage(state, options) {
    if (state.message) {
      state.message.close()
    }
    state.message = Message({
      message: options.message,
      type: options.type || 'success',
      duration: options.duration || 2000,
      offset: 40
    })
  },
  //清空数据
  resetCurrentConversation(state) {
    console.log("清空数据");
    state.isLogin = false,         // tim是否登录
      state.isSDKReady = false,      // TIM SDK 是否 准备好
      state.currentUserProfile = {}, // 用户信息
      state.currentMemberList = [],  // 会话列表 ///不知道要干什么 ////////////////////
      state.currentConversation = {},// 用户的 当前会话
      state.currentMessageList = [], // 当前会话的 聊天记录
      state.nextReqMessageID = '',   // 当前会话的 下一条消息的id
      state.isCompleted = false,     // 当前会话列表 , 是否已经拉完了所有的消息
      state.conversationList = [],   // 所有的 会话列表
      state.intervalID = 0,          // 当前时间
      state.message = undefined
  },
  // 更新timsdk准备状态
  toggleIsSDKReady(state, isSDKReady) {
    state.isSDKReady = typeof isSDKReady === 'undefined' ? !state.isSDKReady : isSDKReady
  },
//  更新用户登录的TIM的状态
  updataIsLogin(state, isLogin) {
    state.isLogin = typeof isLogin === 'undefined' ? !state.isLogin : isLogin
  },
//  更新当前的时间 ,
  updataDate(state) {
    // 指定计数器 , 来获取  , 当前时间
    state.intervalID = setInterval(() => {
      state.current = Date.now()
    }, 500)
  },
  /**
   * 更新会话列表 ,
   * 调用时机 , 触发会话更新事件 , CONVERSATION_LIST_UPDATED
   * @param state
   * @param conversationList
   */
  updateConversationList(state, conversationList) {
    //  判断 , 是否是登录的状态 , 如果是可以进行刷新的操作 , 来进行获取用户的会话列表
    if (state.isLogin) {
      state.conversationList = conversationList
      console.log('开始更新会话列表 ');
      console.log('更新会话列表,共有会话列表：' + (typeof conversationList === Array ? conversationList.length : 0))
    }
  },
  //更新 , 当前的会话
  updateCurrentConversation(state, conversation) {
    console.log('更新当前会话：' + conversation.conversationID)
    state.currentConversation = conversation   //指定当前会话
    state.currentMessageList = []              //指定当前会话的聊天列表
    state.nextReqMessageID = ''                //指定下一条消息的id
    state.isCompleted = false                  // 指定是否还有消息 , 没有请求过来
  },
//   重置当前会话的会话列表
  resetCurrentMemberList(state) {
    console.log('重置当前的会话列表')
    state.currentMemberList = []
  },

  //重置当前会话的所有内容 , 聊天记录 , 等等
  resetCurrent(state) {
    state.currentConversation = {}// 用户的 当前会话
    state.currentMessageList = [] // 当前会话的 聊天记录
    state.nextReqMessageID = '' // 当前会话的 下一条消息的id
  },
  /**
   * 把消息 , 存放到 当前的消息列表里面 , 进行保存起来
   * @param state 操作Vuex的对象
   * @param data 要保存的消息内容
   */
  pushCurrentMessageList(state, data) {
    console.log("将消息保存到当前的会话列表里面");
    //  判断 , 是否存在当前的会话 , 如果存在 , 则进行保存 , 如果不存在 , 则跳过
    if (!state.currentConversation.conversationID) {
      return;
    }
    //  判断 , 传递的消息数据 , 是否是数组对象
    //  1 : 如果是数组对象 , 则是用户第一次获取 消息列表 , 获取的数据是大量的数据 , 所以是数组对象 ,
    //  2 ; 如果不是数组对象 , 则是用户发送消息 , 向当前的会话列表里面, 更新消息的
    if (Array.isArray(data)) {
      //  是数组 筛选出当前会话的消息
      const result = data.filter(item => item.conversationID === state.currentConversation.conversationID)
      //  添加消息
      state.currentMessageList = [...state.currentMessageList, ...result]
      //判断消息的id , 是否是当前会话的id , 则存放带当前的会话列表里面 , 进行保存
    } else if (data.conversationID === state.currentConversation.conversationID) {
      state.currentMessageList = [...state.currentMessageList, data]
    }
  }
}

// 客户端页面, ,调用此函数里面的方法,  用于操作Vue里面的数据
const actions = {

//  登录TIM的函数 , 用于登录 tim , 建立连接
  timLogin({commit, dispatch, rootGetters}) {
    return new Promise((resolve, reject) => {
      //  开始登录 tim
      console.log("开始登录tim");
      //判断 , 是否存在 密钥 , 如果不存在密钥 , 则不能登录成功
      if (!rootGetters.userSign) {
        console.log("缺少密钥");
        reject();
        return;
      }
      //开始 连接 TIM
      tim.login({
        userID: rootGetters.id, //用户的账号
        userSig: rootGetters.userSign //用户的密钥
      }).then((res) => {
        console.log("TIM登录成功");
        //  设置 TIM的信息
        // 更新用户登录tim的状态为已登录
        commit('updataIsLogin', true) //更新用户登录的tim的状态
        commit('updataDate') //更新 , 当前时间
        commit('updateConversationList') //更新会话列表 , 获取实时消息
        //  指定提示消息 , 登录成功
        commit('showMessage', {
          type: 'success',
          message: '登录成功'
        })
        //判断 , 如果 , TIM登录成功 , 并且 , SDK已经准备好  , 则可以获取会话列表
        if (state.isLogin && state.isSDKReady) {
          //获取会话列表 =======================================================================
          console.log("开始获取会话列表");
          dispatch('getConversationList')
        }
        //调用成功的 , 回调函数
        resolve()
      }).catch(err => {
        console.log("Tim登录错误");
        //打印失败的消息 , 用于展示
        commit('showMessage', {
          type: 'error',
          message: '登录失败' + err.message
        })
        //调用失败的回调函数
        reject()
      })
    });
  },
  /**
   * 获取指定会话的 消息 , 第一次打开会话,  获取消息 , 或者 , 下拉加载更多 , 获取消息
   * @param {Object} context
   * @param {String} conversationID   要获取的消息的id C2Ctest
   */
  getMessageList(context, conversationID) {
    //判断 当前会话消息列表是否已经拉完了所有消息
    if (context.state.isCompleted) {
      context.commit('showMessage', {
        message: '所有的消息 , 已经加载完毕',
        type: 'info'
      })
      return;
    }
    //获取, 下一条消息的id     ,  当前会话的消息记录
    const {nextReqMessageID, currentMessageList} = context.state
    //  开始获取 , 消息列表 , 一次 获取 15条消息 ,
    tim.getMessageList({conversationID, nextReqMessageID, count: 15}).then(imReponse => {
      //  数据 , 请求过来1 , 更新下一条消息的id , 下拉加载更多时 要用到
      context.state.nextReqMessageID = imReponse.data.nextReqMessageID
      //获取 , 是否已经拉取完了所有的消息
      context.state.isCompleted = imReponse.data.isCompleted

      // 更新当前消息列表，从头部插入消息 ,
      context.state.currentMessageList = [...imReponse.data.messageList, ...currentMessageList]
      //打印消息的条数 , 是否已经获取了 , 所有的消息
      console.log('获取到的消息条数：' + imReponse.data.messageList.length)
      console.log('消息列表获取成功，是否获取完全部消息：' + context.state.isCompleted)
    })
  },
  /**
   * 获取会话列表 , 刷新按钮 , 获取用户的会话列表
   * @param commit
   * @returns {Promise<unknown>}
   */
  getConversationList({commit}) {
    console.log("开始刷新会话列表");
    return new Promise((resolve, reject) => {
      // 获取会话列表
      tim.getConversationList().then((imResponse) => {
        console.log("会话列表 获取成功");
        //  获取会话列表
        const conversationList = imResponse.data.conversationList //会话列表
        //  更新会话列表
        commit('updateConversationList', conversationList)
        commit('showMessage', {
          message: '获取成功会话列表成功',
          type: 'success'
        })
        resolve()
      }).catch(error => {
        commit('showMessage', {
          message: '获取会话列表失败：' + error.message,
          type: 'error'
        })
        reject()
      })
    });
  },
  /**
   *  切换会话的函数 该函数用于 切换会话 , 获取会话的第一页的数据 ,
   * @param state 操作vuex里面的变量
   * @param commit 调用函数
   * @param dispatch
   * @param conversationID 要进行切换的id账号
   * @returns {*}
   * @constructor
   */
  SwitchTheSession({state, commit, dispatch}, conversationID) {
    console.log("开始切换会话" + conversationID);
    //重置当前的会话列表
    commit('resetCurrentMemberList');
    // 1.切换会话前，将切换前的会话进行已读上报
    if (state.currentConversation.conversationID) {
      dispatch('setCurrentConversationMessageRead')
    }
    // 2.待切换的会话也进行已读上报，也就是目标会话
    tim.setMessageRead({conversationID})
    // 3 ;获取会话信息
    return tim.getConversationProfile(conversationID).then(({data}) => {
      //  3.1获取 , 会话成功 ,更新当前的会话 , 获取返回的当前会话的信息
      commit('updateCurrentConversation', data.conversation);
      //  获取当前会话的消息列表 ,
      dispatch('getMessageList', conversationID);
      return Promise.resolve()
    })
  },
  /**
   * 设置当前会话消息已读
   * @param {*} context
   * @param {*} conversationID
   */
  setCurrentConversationMessageRead({state}) {
    console.log('设置当前会话消息已读')
    // 设置当前会话消息已读
    tim.setMessageRead({conversationID: state.currentConversation.conversationID})
  },

  // /**
  //  * 清空所有的数据
  //  */
  // removeMessage({commit}){
  //   commit('resetCurrentConversation')
  // }

}

// 把数据 , 导出去  ,用于别人引入
export default {
  namespaced: true,
  state,
  mutations,
  actions
}


